package com.uenpay.util.net.uenrequest;

import com.socks.library.KLog;
import com.uenpay.util.crypt.AES;
import com.uenpay.util.crypt.CryptUtils;
import com.uenpay.util.net.http.HttpParam;
import com.uenpay.util.net.retrofit.UenException;
import com.uenpay.util.xml.CreateXML;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by liulou on 2017/4/12.
 * desc:
 */

public final class UenRequest {

    private static final String TAG = "UenRequest";

    public <T> T create(final Class<T> request) {
        return (T) Proxy.newProxyInstance(request.getClassLoader(), new Class<?>[]{request}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getDeclaringClass() == Object.class) {
                    return method.invoke(this, args);
                }
                Map<String, String> map = new HashMap<>();
                if (args != null) {
                    Annotation[][] annotations = method.getParameterAnnotations();

                    for (int k = 0; k < annotations.length; k++) {
                        for (int i = 0; i < annotations[k].length; i++) {
                            if (annotations[k][i] instanceof ParamName) {
                                if (args[k] instanceof String) {
                                    map.put(((ParamName) annotations[k][i]).value(), (String)args[k]);
                                }else{
                                    throw new UenException("UenRequest params type must be String!");
                                }
                            }
                        }
                    }
                }
                String mRequestParam = CreateXML.create(map);
                KLog.xml(TAG, mRequestParam);
                String encryParams = AES.encryptString(mRequestParam, CryptUtils.encryptToMD5(HttpParam.AES_Password));
                return encryParams;
            }
        });
    }
}
